package com.compose.universally.okhttp

import android.annotation.SuppressLint
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.Message
import com.compose.universally.utils.showErrorToast
import com.google.gson.internal.`$Gson$Types`
import java.io.File
import java.lang.reflect.ParameterizedType
import java.lang.reflect.Type

class OKHttpBaseCallBack<T> {
    companion object {
        val headerMap = HashMap<String, Any>()
        var successCode = 200

        // code 对应的字段对应名
        var code = "code"

        // msg 对应的字段对应名
        var msg = "msg"

        // data 对应的字段对应名
        var data = "data"
    }

    var data: Any? = null
    var msg: String? = null
    var code: Int = 0
}

abstract class OKHttpCallBack {
    var type: Type? = null
    open fun onStart() {}
    abstract fun onSuccess(data: Any?)
    open fun onError(code: Int, error: String?) {
        showErrorToast(error!!)
    }

    open fun onInfo(info: String) {}
    open fun onEnd() {}
    open fun onResponse(response: String) {}

    init {
        // Type是 Java 编程语言中所有类型的公共高级接口。它们包括原始类型、参数化类型、数组类型、类型变量和基本类型。
        val superclass = javaClass.genericSuperclass
        type = if (superclass is Class<*>) {
            null
        } else {
            // ParameterizedType参数化类型，即泛型
            val parameterized = superclass as ParameterizedType?
            // getActualTypeArguments获取参数化类型的数组，泛型可能有多个
            // 将Java 中的Type实现,转化为自己内部的数据实现,得到gson解析需要的泛型
            `$Gson$Types`.canonicalize(parameterized!!.actualTypeArguments[0])
        }
    }


    inner class Builder {
        // 请求开始
        val start = 10001

        // 请求成功
        val success = 10002

        // 请求出错
        val error = 10003

        // 请求结束
        val end = 10004

        // Message信息
        val info = 10005

        // Response
        val response = 10007
        fun start() {
            handler.sendEmptyMessage(start)
        }

        fun error(code: Int, err: String?) {
            val message = Message()
            val bundle = Bundle()
            bundle.putInt("code", code)
            bundle.putString("msg", err)
            message.obj = bundle
            message.what = error
            handler.sendMessage(message)
        }

        fun success(data: Any?) {
            val message = Message()
            message.obj = data
            message.what = success
            handler.sendMessage(message)
        }

        fun end() {
            handler.sendEmptyMessage(end)
        }


        fun info(string: String) {
            val message = Message()
            message.obj = string
            message.what = info
            handler.sendMessage(message)
        }

        fun onResponse(string: String) {
            val message = Message()
            message.obj = string
            message.what = response
            handler.sendMessage(message)
        }

        @SuppressLint("HandlerLeak")
        var handler: Handler = object : Handler(Looper.getMainLooper()) {
            override fun handleMessage(msg: Message) {
                when (msg.what) {
                    start -> onStart()
                    success -> onSuccess(msg.obj)
                    error -> {
                        if (msg.obj != null) {
                            val bundle = msg.obj as Bundle
                            onError(bundle.getInt("code"), bundle.getString("msg"))
                        }
                        onEnd()
                    }

                    end -> onEnd()
                    info -> onInfo(msg.obj as String)
                    response -> onResponse(msg.obj as String)
                }
            }
        }
    }
}

/**
 * 下载文件返回
 */
abstract class OKHttpFileCallBack {
    abstract fun onStart(totalSize: Int)
    abstract fun onProgress(size: Int)
    abstract fun onSuccess(file: File?)
    abstract fun onError(err: String?)
    open fun onEnd() {}

    inner class Builder {
        private val start = 100001
        private val success = 100002
        private val error = 100003
        private val end = 100004
        private val progress = 100005
        fun error(err: String?) {
            val message = Message()
            message.obj = err
            message.what = error
            handler.sendMessage(message)
        }

        fun start(total: Long) {
            val message = Message()
            message.obj = total.toInt()
            message.what = start
            handler.sendMessage(message)
        }

        fun progress(sum: Long) {
            // 下载中更新进度条
            val message = Message()
            message.obj = sum.toInt()
            message.what = progress
            handler.sendMessage(message)
        }

        fun success(file: File?) {
            // 下载完成
            val message = Message()
            message.obj = file
            message.what = success
            handler.sendMessage(message)
        }

        @SuppressLint("HandlerLeak")
        var handler: Handler = object : Handler(Looper.getMainLooper()) {
            override fun handleMessage(msg: Message) {
                when (msg.what) {
                    start -> onStart(msg.obj as Int)
                    progress -> onProgress(msg.obj as Int)
                    success -> onSuccess(msg.obj as File)
                    error -> {
                        if (msg.obj != null) {
                            onError(msg.obj.toString())
                        }
                        onEnd()
                    }

                    end -> onEnd()
                }
            }
        }

    }
}